/*
 * @Author: sichuntian sichuntian@smartmappingtek.com
 * @Date: 2024-04-18 11:09:13
 * @LastEditors: sichuntian sichuntian@smartmappingtek.com
 * @LastEditTime: 2024-04-18 17:35:42
 * @Description:
 *
 */
import * as mars3d from "mars3d"
import "mars3d-space"
const Cesium = mars3d.Cesium
import * as turf from "@turf/turf"
class Measure {
  constructor(marsMap) {
    this.marsMap = marsMap
    this.measureLayer = new mars3d.layer.GraphicLayer()
    this.marsMap.addLayer(this.measureLayer)

    this.measure = new mars3d.thing.Measure({
      hasEdit: true,
      label: {
        color: "#ffffff",
        font_family: "楷体",
        font_size: 20,
        background: false,
      },
    })

    /* 控制拖动测绘点的时候只在模型上取点，拖动完成之后回复正常*/
    const that = this
    this.measure.on(mars3d.EventType.editMouseMove, function (e) {
      that.marsMap.onlyPickModelPosition = that.hasModel(e.windowPosition.x, e.windowPosition.x)
    })
    this.measure.on(mars3d.EventType.editMovePoint, function (e) {
      that.marsMap.onlyPickModelPosition = that.hasModel(e.windowPosition.x, e.windowPosition.x)
    })
    // /* 控制拖动测绘点的时候只在模型上取点，拖动完成之后回复正常*/

    this.marsMap.addThing(this.measure)

    // 通视分析准备工作
    this.sightline = new mars3d.thing.Sightline({
      visibleColor: new Cesium.Color(0, 1, 0, 0.4),
      hiddenColor: new Cesium.Color(1, 0, 0, 0.4),
      // depthFailColor: Cesium.Color.fromCssColorString("#409eff"),
    })
    this.marsMap.addThing(this.sightline)
    // 更改右键绑定事件
    this.marsMap.unbindContextMenu()
    const defaultContextmenuItems = this.marsMap.getDefaultContextMenu()
    defaultContextmenuItems.length = 0
    // 地图标记功能
    defaultContextmenuItems.push({
      text: "添加标记",
      icon: "fa fa-map-marker",
      show: function (e) {
        return Cesium.defined(e.cartesian)
      },
      callback: (e) => {
        const pos = mars3d.LngLatPoint.fromCartesian(e.cartesian)
        let pointStr = `${pos.lng},${pos.lat},${pos.alt}`
        const graphic = new mars3d.graphic.DivGraphic({
          position: e.cartesian,
          style: {
            html: `<div class="marsImgPanel2">
                    <div class="title">标记信息</div>
                    <div class="content">经度：${pos.lng}<br/>纬度：${pos.lat}<br/>高度：${pos.alt}</div>
                  </div >`,
            horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            offsetY: 40,
            depthTest: false,
          },
          attr: { key: "signboard", signboardId: pointStr },
          testPoint: {
            color: "#ff0000",
            pixelSize: 4,
          },
          highlight: {},
          // pointerEvents: false, // false时不允许拾取和触发任意鼠标事件，但可以穿透div缩放地球
        })

        graphic.bindContextMenu([
          {
            text: "删除对象",
            icon: "fa fa-trash-o",
            show: (event) => {
              const graphic = event.graphic
              if (!graphic || graphic.isDestroy) {
                return false
              } else {
                return true
              }
            },
            callback: (e) => {
              this.measureLayer.removeGraphic(graphic)
            },
          },
        ])
        this.measureLayer.addGraphic(graphic)
        graphic.testPoint = true
      },
    })
    // 空间距离测量
    defaultContextmenuItems.push({
      text: "空间距离",
      icon: "contextmenu-icon fa fa-minus",
      show: function (e) {
        return Cesium.defined(e.cartesian)
      },
      callback: (e) => {
        const isHasModel = this.hasModel(e.windowPosition.x, e.windowPosition.x)
        this.measureDistance(isHasModel)
      },
    })
    // 三角距离测量
    defaultContextmenuItems.push({
      text: "三角距离测量",
      icon: "contextmenu-icon fa fa-sort-amount-asc",
      show: function (e) {
        return Cesium.defined(e.cartesian)
      },
      callback: (e) => {
        const isHasModel = this.hasModel(e.windowPosition.x, e.windowPosition.x)
        this.heightTriangle(isHasModel)
      },
    })
    // 角度测量
    defaultContextmenuItems.push({
      text: "角度测量",
      icon: "contextmenu-icon fa fa-road",
      show: function (e) {
        return Cesium.defined(e.cartesian)
      },
      callback: (e) => {
        const isHasModel = this.hasModel(e.windowPosition.x, e.windowPosition.x)
        this.measureAngle(isHasModel)
      },
    })
    // 水平面积测量
    defaultContextmenuItems.push({
      text: "水平面积测量",
      icon: "contextmenu-icon fa fa-medium",
      show: function (e) {
        return Cesium.defined(e.cartesian)
      },
      callback: (e) => {
        const isHasModel = this.hasModel(e.windowPosition.x, e.windowPosition.x)
        this.measureArea(isHasModel)
      },
    })
    // 通视分析
    defaultContextmenuItems.push({
      text: "通视分析",
      icon: "contextmenu-icon fa fa-eye",
      show: function (e) {
        return Cesium.defined(e.cartesian)
      },
      callback: (e) => {
        const isHasModel = this.hasModel(e.windowPosition.x, e.windowPosition.x)
        this.drawLine(isHasModel)
      },
    })
    // 清除所有
    defaultContextmenuItems.push({
      text: "清除所有",
      icon: "contextmenu-icon fa fa-trash-o",
      show: function (e) {
        return Cesium.defined(e.cartesian)
      },
      callback: (e) => {
        this.clearMeasureLayer()
      },
    })
    this.marsMap.bindContextMenu(defaultContextmenuItems)
  }
  // 空间距离测量
  measureDistance(hasModel) {
    this.marsMap.onlyPickModelPosition = hasModel
    const distancePromise = this.measure.distance({})
    distancePromise.then((res) => {
      this.marsMap.onlyPickModelPosition = false
    })
  }
  // 角度测量
  measureAngle(hasModel) {
    this.marsMap.onlyPickModelPosition = hasModel
    const promise = this.measure.angle({})
    promise.then((event) => {
      this.marsMap.onlyPickModelPosition = false
    })
  }
  // 贴地距离测量
  measureSurfaceLength(hasModel) {
    this.marsMap.onlyPickModelPosition = hasModel
    const promise = this.measure.distanceSurface({
      showAddText: true,
      exact: false, // 是否进行精确计算， 传false时是否快速概略计算方式，该方式计算精度较低，但计算速度快，仅能计算在当前视域内坐标的高度
      // unit: 'm', //支持传入指定计量单位
      style: {
        color: "#ffff00",
        width: 3,
        clampToGround: true, //是否贴地
      },
    })
    promise.then((event) => {
      this.marsMap.onlyPickModelPosition = false
    })
  }
  // 水平面积测量
  measureArea(hasModel) {
    this.marsMap.onlyPickModelPosition = hasModel
    const promise = this.measure.area({})
    promise.then((res) => {
      this.marsMap.onlyPickModelPosition = false
    })
  }
  // 贴地面积测量
  measureSurfaceeArea(hasModel) {
    this.marsMap.onlyPickModelPosition = hasModel
    const promise = this.measure.areaSurface({
      style: {
        color: "#ffff00",
      },
      splitNum: 10, // step插值分割的个数
      exact: false,
    })
    promise.then((res) => {
      this.marsMap.onlyPickModelPosition = false
    })
  }
  // 三角高度测量
  heightTriangle(hasModel) {
    this.marsMap.onlyPickModelPosition = hasModel
    const promise = this.measure.heightTriangle({})
    promise.then((event) => {
      this.marsMap.onlyPickModelPosition = false
    })
  }
  //绘制成功后创建点
  createPoint(position, isFirst) {
    const graphic = new mars3d.graphic.PointEntity({
      position,
      style: {
        color: Cesium.Color.fromCssColorString("#3388ff"),
        pixelSize: 6,
        outlineColor: Cesium.Color.fromCssColorString("#ffffff"),
        outlineWidth: 2,
        scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 8.0e6, 0.2),
        clampToGround: true, //是否贴地
        label: {
          text: isFirst ? "观察位置" : "目标点",
          font_size: 17,
          font_family: "楷体",
          color: Cesium.Color.AZURE,
          outline: true,
          outlineColor: Cesium.Color.BLACK,
          outlineWidth: 2,
          horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
          pixelOffset: new Cesium.Cartesian2(0, -20), // 偏移量
          distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
            0.0,
            2000000
          ),
        },
      },
    })
    this.measureLayer.addGraphic(graphic)

    return graphic
  }
  // 通视分析
  drawLine() {
    const this_ = this
    this.measureLayer.clear()
    this.measureLayer.startDraw({
      type: "polyline",
      maxPointNum: 2,
      drawShow: true,
      style: {
        color: "#55ff33",
        width: 3,
      },
      success: function (graphic) {
        const positions = graphic.positionsShow
        this_.measureLayer.clear()

        const center = positions[0]
        const targetPoint = positions[1]
        this_.sightline.add(center, targetPoint, { offsetHeight: 0.1 })

        this_.createPoint(center, true)
        this_.createPoint(targetPoint, false)
      },
    })
  }
  // 清除所有的测量痕迹
  clearMeasureLayer() {
    this.measure.clear()
    this.sightline.clear()
    this.measureLayer.clear()
  }
  // 判断点击位置是否有模型
  hasModel(x, y) {
    let pickCartesian2 = new Cesium.Cartesian2(x, y)
    let feature = this.marsMap.viewer.scene.pick(pickCartesian2);
    if (feature) {
      console.log("有模型")
      return true
    } else {
      console.log("没有模型")
      return false
    }
  }
}
export default Measure
